﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using HA.ModFlow .Infrastructure;

namespace HA.MT3DMS.FileLayer
{
    
    
    public   class MT3DResultDataSetReader:DataSetReader
    {

        #region
       /// <summary>
       /// 输入参数为要读取的文件的绝对路径
       /// </summary>
       /// <param name="mt3dFilePath"></param>
        public MT3DResultDataSetReader(string mt3dFilePath,List <int [,]> iBounds)
        {
            this.filePath = mt3dFilePath;

            this.effIBounds = iBounds;

        }

        #endregion

        #region 字段属性

        /// <summary>
        /// 要读取的文件的路径
        /// </summary>
        string filePath = "";


        List<int[,]> effIBounds;
       /// <summary>
       /// 存储有效单元的标志信息
       /// </summary>
        public  List<int[,]> EffIBounds
        {
            get { return effIBounds; }
            //set { effIBounds = value; }
        }




        int transStep = 1;//传输步长
        /// <summary>
        /// 传输步长
        /// </summary>
        public int TransStep
        {
            get { return transStep; }
            set { transStep = value; }
        }
        int timeStep = 1;//时间步长
        /// <summary>
        /// 时间步长
        /// </summary>
        public int TimeStep
        {
            get { return timeStep; }
            set { timeStep = value; }
        }
        int stressStep = 1;//应力期
        /// <summary>
        /// 应力期
        /// </summary>
        public int StressStep
        {
            get { return stressStep; }
            set { stressStep = value; }
        }
        double time = 1;//时间
        /// <summary>
        /// 时间
        /// </summary>
        public double Time
        {
            get { return time; }
            set { time = value; }
        }
        string conc = "";//浓度
        /// <summary>
        /// 浓度标志
        /// </summary>
        public string Conc
        {
            get { return conc; }
            set { conc = value; }
        }
        int col = 1;//总列数 J
        /// <summary>
        /// 网格总列数  J
        /// </summary>
        public int Col
        {
            get { return col; }
            set { col = value; }
        }
        int row = 1;//总行数 I
        /// <summary>
        /// 网格总行数  I
        /// </summary>
        public int Row
        {
            get { return row; }
            set { row = value; }
        }
        int layer = 1;//总层数 K
        /// <summary>
        /// 网格总层数  K
        /// </summary>
        public int Layer
        {
            get { return layer; }
            set { layer = value; }
        }







        #endregion


       

        #region 公用方法


        #endregion

        #region 父类方法的重写
        /// <summary>
        /// 出错后 返回 null
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public override DataSet ReadData(int index)
        {



            //说明：该读取文件数据的方法的做了一些前提的假设  1，文件内容很规范，第一行为参数信息，长度为8个字符串，例如：    29     1     1    100.0      CONCENTRATION       21    15     8
            //2，从第二行开始是浓度数据信息，且数据完整，即数据的个数符合 21    15     8 定义的网格的单元格数
            //3，数据之间没有空行

            //其他的情况可能会导致该方法读取文件错误

            CellCenterDataSet3d mt3dDataResult=null ;


            System.IO.FileStream fs = null;
            System.IO.StreamReader sr = null;

            try
            {

                if (System.IO.File.Exists(filePath))
                {
                    fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open);
                    sr = new System.IO.StreamReader(fs);

                    #region 读取文件

                    if (sr.EndOfStream != true)
                    {
                        string line1 = sr.ReadLine();
                        if (line1 != null)
                        {
                            if (line1.Trim() != "")
                            {
                                int strNum = GetStringNumber(line1);

                                if (strNum > 0)
                                {
                                    //例如：    29     1     1    100.0      CONCENTRATION       21    15     8
                                    //下面这句代码好危险，好菜。。。。。。。。。。。

                                    if (strNum == 8)
                                    {
                                        #region 读取数据


                                        string str1 = GetSpecifyString(line1, 1);
                                        string str2 = GetSpecifyString(line1, 2);
                                        string str3 = GetSpecifyString(line1, 3);
                                        string str4 = GetSpecifyString(line1, 4);
                                        string str5 = GetSpecifyString(line1, 5);
                                        string str6 = GetSpecifyString(line1, 6);
                                        string str7 = GetSpecifyString(line1, 7);
                                        string str8 = GetSpecifyString(line1, 8);

                                        if (str1 == null || str2 == null || str3 == null || str4 == null || str5 == null || str6 == null || str7 == null || str8 == null)
                                        {

                                        }
                                        else
                                        {
                                            #region 存储第一行数据

                                            int transStep = Convert.ToInt32(str1);//传输步长
                                            int timeStep = Convert.ToInt32(str2);//时间步长
                                            int stressStep = Convert.ToInt32(str3);//应力期
                                            double time = Convert.ToDouble(str4);//时间
                                            string conc = str5;//浓度
                                            int col = Convert.ToInt32(str6);//总列数 J
                                            int row = Convert.ToInt32(str7);//总行数 I
                                            int layer = Convert.ToInt32(str8);//总层数 K

                                            this.transStep = transStep;
                                            this.timeStep = timeStep;
                                            this.stressStep = stressStep;
                                            this.time = time;
                                            this.conc = conc;
                                            this.col = col;
                                            this.row = row;
                                            this.layer = layer;


                                            //readConcFileResult.ConcFilePath = filePath;


                                            #endregion

                                            //具体的浓度数据存放位置还未确定  暂时存储在三维数组中

                                            #region 浓度数据

                                            double[, ,] conValue = new double[row, col, layer];

                                            if (sr.EndOfStream != true)
                                            {
                                                for (int K = 0; K < layer; K++)
                                                {
                                                    for (int I = 0; I < row; I++)
                                                    {
                                                        for (int J = 0; J < col; J++)
                                                        {
                                                            if (sr.EndOfStream != true)
                                                            {
                                                                //不清楚数据的存放顺序  暂时按照 先遍历列 再遍历行 在遍历层的顺序

                                                                string str = sr.ReadLine();

                                                                if (str != null)
                                                                {
                                                                    if (str.Trim() != "")
                                                                    {
                                                                        int numStr = GetStringNumber(str);
                                                                        if (numStr > 0)
                                                                        {
                                                                            string concentrationStr = GetSpecifyString(str, 1);
                                                                            if (concentrationStr != null)
                                                                            {
                                                                                double concentrationValue = Convert.ToDouble(concentrationStr);

                                                                                conValue[I, J, K] = concentrationValue;

                                                                            }
                                                                            else
                                                                            {
                                                                                ShowErrorMessage(mt3dDataResult, fs, sr, filePath);
                                                                                return mt3dDataResult;
                                                                            }


                                                                        }
                                                                        else
                                                                        {
                                                                            ShowErrorMessage(mt3dDataResult, fs, sr, filePath);
                                                                            return mt3dDataResult;
                                                                        }

                                                                    }
                                                                    else
                                                                    {
                                                                        ShowErrorMessage(mt3dDataResult, fs, sr, filePath);
                                                                        return mt3dDataResult;

                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    ShowErrorMessage(mt3dDataResult, fs, sr, filePath);
                                                                    return mt3dDataResult;
                                                                }


                                                            }// if (sr.EndOfStream != true) 结束
                                                        } // for (int J = 0; J < col ; J++) 结束           
                                                    }// for (int I = 0; I < row ; I++)结束

                                                }// for (int K = 0; K < layer; K++)结束


                                            }

                                            //readConcFileResult.ConcValue = conValue;






                                            #endregion 读取浓度数据结束


                                            mt3dDataResult = new CellCenterDataSet3d(conValue,this.effIBounds );


                                            mt3dDataResult.Nrows = row;
                                            mt3dDataResult.Ncols = col;
                                            mt3dDataResult.Nlayers = layer;



                                        }



                                        #endregion

                                    }

                                }

                            }
                            else
                            { 
                            
                            
                            }
                        }
                        else
                        { 
                        
                        
                        }

                    }


                    #endregion


                    sr.Close();
                    fs.Close();

                }
                else
                {
                    //System.Windows.Forms.MessageBox.Show("您要读取MT3D结果文件: " + filePath + "不存在！请检查！");

                }

                return mt3dDataResult;
            }
            catch 
            {
                ShowErrorMessage(mt3dDataResult, fs, sr, filePath);

                return mt3dDataResult;

            }





        }



        public override List<DataSet> ReadData()
        {
            //暂时未实现

            return null;

            //throw new NotImplementedException();



        }




        #endregion


        #region 内部方法

        /// <summary>
        /// 判断给定的文件是否存在
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private static bool IsFileExist(string filePath)
        {
            try
            {
                if (System.IO.File.Exists(filePath))
                {
                    return true;
                }
                else
                {
                    return false;
                }

            }
            catch
            {
                return false;
            }

        }

        /// <summary>
        /// 得到一行字符串的个数
        /// </summary>
        /// <param name="Str">一行文字</param>
        /// <returns></returns>
        private static int GetStringNumber(string Str)
        {
            Str = " " + Str + " "; //在字符串前后各加一个空，以便于后面处理
            int n = 0, n1 = 0, n2 = 0;

            if (Str != null && Str.Length > 2)
            {
                while (n2 >= 0)
                {
                    n1 = n2;
                    n2 = Str.IndexOf(" ", n1 + 1);
                    if ((n2 - n1) > 1)  //如果不是连续的空格，开始计数
                    {
                        n++;
                    }
                }
            }

            return n;

        }


        /// <summary>
        /// 得到指定位置的字符串,字符创长度为0或者出错返回 null
        /// </summary>
        /// <param name="Str"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private static string GetSpecifyString(string Str, int index)
        {
            Str = " " + Str + " ";
            string SubStr = "";
            int n = 0, n1 = 0, n2 = 0;

            try
            {

                //while (n2 >= 0)
                //{
                //    n1 = n2;
                //    n2 = Str.IndexOf(" ", n1 + 1);
                //    if ((n2 - n1) > 1)  //如果不是连续的空格，开始计数
                //    {
                //        n++;
                //        if (n == index)
                //        {
                //            SubStr = Str.Substring(n1, n2 - n1);
                //            return SubStr;
                //        }
                //    }
                //}

                //上下两种方法都可以

                for (int i = 0; i < Str.Length; i++)
                {

                    if (Str.Substring(i, 1) != " ")
                    {
                        n1 = i;
                        n2 = Str.IndexOf(" ", n1);
                        SubStr = Str.Substring(n1, n2 - n1);
                        i = n2;
                        n++;
                        if (n == index)
                        {
                            return SubStr;

                        }
                    }

                }
                return null;
            }
            catch
            {
                return null;
            }

        }

        /// <summary>
        /// 出错时调用 错做包括：关闭读取文件的流，错误提示，初始化返回结果对象readConcFileResult
        /// </summary>
        /// <param name="readConcFileResult"></param>
        /// <param name="fs"></param>
        /// <param name="sr"></param>
        /// <param name="filePath"></param>
        private static void ShowErrorMessage(CellCenterDataSet3d  readConcFileResult, System.IO.FileStream fs, System.IO.StreamReader sr, string filePath)
        {
            if (sr != null)
            {
                sr.Close();
            }
            if (fs != null)
            {
                fs.Close();
            }

            System.Windows.Forms.MessageBox.Show("读取MT3D结果文件: " + filePath + "的过程出错！");

            readConcFileResult =null ;

        }



        #endregion






    }



}
